devfandomcom-20200223-history
Lua templating/Optimisation
Optimisation is generally only necessary when lua modules are misused or inefficient. Important note "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." The fallacy of premature optimization. . http://ubiquity.acm.org/article.cfm?id=1513451 General guidelines If for whatever reason your modules are exceeding the limit, you should then consider optimising. Whenever possiblehttp://www.lua.org/gems/sample.pdf : * Use local functions or variables * Avoid nested functions * Use arrays instead of tables (hashing) * Use local variables instead of indexing tables Simple optimisations such as copying a global function (e.g. string.match) may greatly improve performance of a module. Tip: Use os.clock() before and after a code "chunk" and subtract the two results to evaluate the code section's performance. String vs table concatenation When dealing with potentially huge strings, it is more efficient to add them to a table and use table.concat rather than simply using "join" or concatenating them http://www.lua.org/pil/11.6.html. |-|Manual concatenation= -- This is slower local people = {"John", "Mary", "Parker", "Sue", "Anonymous", "..."} local text = "" for i = 1, #people do if i > 1 then text = ", " .. text end text = text .. peoplei end print(text) |-|table.concat= -- This is faster local people = {"John", "Mary", "Parker", "Sue", "Anonymous", "..."} local text = table.concat(people, ", ") print(text) Use tables for SQL-IN alike compares This means that instead of having a lot of if statements a better alternative is to put them all in a set-like tablehttp://stackoverflow.com/a/12865406. For example, this is a typical if structure: local function foo(value) if value "foo" or value "bar" or value "baz" or value "qux" or value "lorem" or value "ipsum" then return "something" end return "something else" end ... and this is a more efficient, table-based one: local function foo(value) local validValues = { foo = true, bar = true, baz = true, qux = true, lorem = true, ipsum = true } if validValuesvalue then return "something" end return "something else" end Note that you can use any truthy value, instead of just true. Templates Using too many template transclusions in a single page is one common problem that affects the speed of lua. Each invocation will count towards the lua limit. There are multiple techniques to overcome this: * Consolidate - move all code to a module, and restructure it to only be called fewer times * Rewrite the code to be more efficient. Change template "databases" into data modules Making templates databases causes a lot of issues such as becoming cumbersome to use, and slower if they use parser functions. One idea is adding them to a module, as described in Lua templating/Converting Wikitext templates. If the template is used several times on a page, consider using mw.loadData to load its data, instead of require: local data = mw.loadData("Module:Mystuff") return data[frame.args1] Avoid multiple invocations to the same module Instead of this for example: local p = {} function p.showpopulation(frame) local pop = {china= 50, australia = 20, ghana = 10} return pop[frame.args1] end return p Do this: local p = {} function p.showpopulation(frame) local pop = {china= 50, australia = 20, ghana = 10} local args = frame.args return pop[args1] .." ".. (pop[args2] or "") .. " " ..(pop[args3] or "") end return p References Category:Lua